package com.leo.core.config;

import java.io.IOException;

import javax.sql.DataSource;

import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import com.alibaba.druid.pool.DruidDataSource;

import lombok.extern.slf4j.Slf4j;

/**
 * @ClassName: ApplicationContextConfig
 * @Description: 注册bean配置类，类似我们的applicationContext.xml文件 @Scope类型： singleton 表示在spring容器中的单例，通过spring容器获得该bean时总是返回唯一的实例 prototype表示每次获得bean都会生成一个新的对象 request表示在一次http请求内有效（只适用于web应用） session表示在一个用户会话内有效（只适用于web应用）
 *               globalSession表示在全局会话内有效（只适用于web应用）
 * @Author: leo825
 * @Date: 2020-05-14 21:33
 * @Version: 1.0
 */
@Slf4j
@Configuration
public class ApplicationContextConfig extends WebMvcConfigurationSupport
{
    /**
     * 加载配置文件，类似之前配置文件中的： <bean id="configProperties" class="org.springframework.beans.factory.config.PropertiesFactoryBean">          <property name="locations">               <list>                  
     * <value>classpath:*.properties</value>             </list> <property/> </bean>        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">  
     * <property name="properties" ref="configProperties"/> </bean>
     *
     * @return
     */
    @Bean(name = "configProperties")
    public PropertiesFactoryBean propertiesFactoryBean()
    {
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        propertiesFactoryBean.setLocation(new ClassPathResource("application.properties"));
        propertiesFactoryBean.setSingleton(true);
        log.info("propertiesFactoryBean注册完毕");
        return propertiesFactoryBean;
    }
    
    @Bean(name = "propertyConfiguer")
    public MyPropertyPlaceholder preferencesPlaceholderConfigurer(PropertiesFactoryBean configProperties)
        throws IOException
    {
        MyPropertyPlaceholder propertyConfiguer = new MyPropertyPlaceholder();
        propertyConfiguer.setProperties(configProperties.getObject());
        log.info("preferencesPlaceholderConfigurer注册完毕");
        return propertyConfiguer;
    }
    
    /**
     * 创建jdbcTemplate
     * 
     * @return
     */
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource)
    {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource);
        log.info("jdbcTemplate注册完毕");
        return jdbcTemplate;
    }
    
    /**
     * 数据库连接配置
     */
    @Bean(initMethod = "init", destroyMethod = "close")
    public DataSource dataSource()
    {
        log.info("Configuring Datasource");
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(MyPropertyPlaceholder.getProperty("datesource.driverClassName"));
        druidDataSource.setUrl(MyPropertyPlaceholder.getProperty("datesource.url"));
        druidDataSource.setUsername(MyPropertyPlaceholder.getProperty("datesource.username"));
        druidDataSource.setPassword(MyPropertyPlaceholder.getProperty("datesource.password"));
        druidDataSource.setMaxActive(10);
        druidDataSource.setMaxWait(60000);
        druidDataSource.setMinIdle(1);
        druidDataSource.setValidationQuery("SELECT 1");
        druidDataSource.setTestWhileIdle(true);
        druidDataSource.setTestOnBorrow(false);
        druidDataSource.setTestOnReturn(false);
        /**
         * configuration exception handling
         */
        druidDataSource.setQueryTimeout(15); // 查询超时时间15s
        // 通过datasource.getConnontion() 取得的连接必须在removeAbandonedTimeout这么多秒内调用close(),要不强制关闭.(就是conn不能超过指定的租期)
        druidDataSource.setRemoveAbandoned(true);
        druidDataSource.setRemoveAbandonedTimeout(600); // 一个连接的租期10分钟，超时会被强制关闭
        druidDataSource.setLogAbandoned(true);
        log.info("driverManagerDataSource注册完毕");
        return druidDataSource;
    }
}
